package com.yyplatform.frontend.platform.account.service.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.tuple.Pair;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.yyplatform.frontend.platform.account.config.AlipayMiniAppConfig;
import com.yyplatform.frontend.platform.account.dto.LoginAlipayAppFormDTO;
import com.yyplatform.frontend.platform.account.dto.LoginResultDTO;
import com.yyplatform.frontend.platform.account.entity.UserAuthEntity;
import com.yyplatform.frontend.platform.account.entity.UserEntity;
import com.yyplatform.frontend.platform.account.repository.UserAuthRepository;
import com.yyplatform.frontend.platform.account.repository.UserRepository;
import com.yyplatform.frontend.platform.account.service.AlipayAppLoginService;
import com.yyplatform.frontend.infra.enums.UserLoginTypeEnum;
import com.yyplatform.frontend.infra.exception.ErrorCode;
import com.yyplatform.frontend.infra.exception.ServiceException;
import com.yyplatform.frontend.infra.web.jwt.JwtTokenService;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * Created on 2024-10-18
 */
@Service
@Slf4j
@AllArgsConstructor
public class AlipayAppLoginServiceImpl implements AlipayAppLoginService {

    private AlipayMiniAppConfig alipayMiniAppConfig;
    private UserRepository userRepository;
    private UserAuthRepository userAuthRepository;
    private JwtTokenService jwtTokenService;

    @Override
    public LoginResultDTO loginCheck(LoginAlipayAppFormDTO loginFormDTO) {

        try {
            AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                    alipayMiniAppConfig.getAppId(),                    // 1. 填入appid
                    alipayMiniAppConfig.getPrivateKey(),            // 2. 填入私钥
                    "json",
                    "GBK",
                    alipayMiniAppConfig.getAlipayPublicKey(),         // 3. 填入公钥
                    "RSA2");
            AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
            request.setGrantType("authorization_code");
            request.setCode(loginFormDTO.getAuthCode());        // 4. 填入前端传入的授权码authCode
            request.setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");    // 0. 不用管

            AlipaySystemOauthTokenResponse response = alipayClient.execute(request);

            if (response == null || !response.isSuccess()) {
                throw ServiceException.of(ErrorCode.ALIPAY_MIN_APP_LOGIN_SERVER_ERROR);
            }

            return loginCheck2(response);


        } catch (Exception e) {
            log.error("alipay min app login error", e);
            throw ServiceException.of(ErrorCode.ALIPAY_MIN_APP_LOGIN_SERVER_ERROR);
        }


    }

    private LoginResultDTO loginCheck2(AlipaySystemOauthTokenResponse response) {
        UserAuthEntity userAuthEntity =
                userAuthRepository.findByLoginTypeAndIdentifier(UserLoginTypeEnum.ALIPAY_MIN_APP.getValue(),
                        response.getUserId());
        if (userAuthEntity != null) {
            UserEntity userEntity = userRepository.getReferenceById(userAuthEntity.getUserId());

            // todo 更新信息，可选

            return buildLoginResult(userEntity, userAuthEntity);
        }

        Pair<UserEntity, UserAuthEntity> pair = newAlipayAppUser(response);

        return buildLoginResult(pair.getLeft(), pair.getRight());
    }

    private Pair<UserEntity, UserAuthEntity> newAlipayAppUser(AlipaySystemOauthTokenResponse response) {

        UserEntity userEntity = new UserEntity();

        AlipayUserInfoShareResponse userInfoShareResponse = null;
        try {
            userInfoShareResponse = getAliUserInfo(response.getAccessToken());
        } catch (Exception e) {
            log.error("alipay min app login error", e);
            throw ServiceException.of(ErrorCode.ALIPAY_MIN_APP_LOGIN_SERVER_ERROR);
        }

        if (userInfoShareResponse != null && userInfoShareResponse.isSuccess()) {
            userEntity.setUserName(userInfoShareResponse.getUserName());
            userEntity.setNickname(userInfoShareResponse.getNickName());

        } else {

        }

        userRepository.save(userEntity);


        UserAuthEntity userAuthEntity = new UserAuthEntity();
        userAuthEntity.setUserId(userEntity.getId());

        userAuthRepository.save(userAuthEntity);


        return Pair.of(userEntity, userAuthEntity);
    }


    private LoginResultDTO buildLoginResult(UserEntity userEntity, UserAuthEntity userAuthEntity) {

        Map<String, Object> data = new HashMap<>();
        data.put("userId", userEntity.getId());
        data.put("loginType", userAuthEntity.getLoginType());
        data.put("identifier", userAuthEntity.getIdentifier());


        String jwtToken = jwtTokenService.encode(String.valueOf(userEntity.getId()), data);
        LoginResultDTO loginResultDTO = new LoginResultDTO();

        loginResultDTO.setJwtToken(jwtToken);
        loginResultDTO.setLoginType(UserLoginTypeEnum.ALIPAY_MIN_APP.getValue());
        loginResultDTO.setIdentifier(userAuthEntity.getIdentifier());


        return loginResultDTO;
    }


    // 获取支付宝用户信息
    private AlipayUserInfoShareResponse getAliUserInfo(String accessToken) throws Exception {
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                alipayMiniAppConfig.getAppId(),                    // 1. 填入appid
                alipayMiniAppConfig.getPrivateKey(),            // 2. 填入私钥
                "json",
                "GBK",
                alipayMiniAppConfig.getAlipayPublicKey(),         // 3. 填入公钥
                "RSA2");
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = alipayClient.execute(request, accessToken);
        if (response.isSuccess()) {
            // System.out.println("获取会员信息 - 调用成功");
            return response;
        }

        return null;
    }


}
